/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin			*/
/*	Project:	GlbCloud			*/
/*	Author:		gong_libin			*/
/*	Date:		2012_01_14			*/
/*	Bloom:		MrBloom.cpp			*/
/********************************************************/

#include "MrBloom.h"

CMrBloom::CMrBloom()
{
}

CMrBloom::~CMrBloom()
{
}

void CMrBloom::MrBloomClose()
{
	CMrFile::MrFileMunmap(0);
	CMrFile::MrFileClose();

	return;
}

int CMrBloom::MrBloomOpen(char* pszFile)
{
	if (MR_FAILURE == CMrFile::MrFileOpen(pszFile, O_CREAT | O_EXCL | MR_O_RDWR)) {
		if (MR_FAILURE == CMrFile::MrFileOpen(pszFile, MR_O_RDWR)) {
			return MR_FAILURE;
		}
	}
	else {
		CMrFile::MrFileTruncate(pszFile, MR_BLOOM_SIZE);
	}

	if (MR_FAILURE == CMrFile::MrFileMmap(MR_P_READ | MR_P_WRITE, MR_M_SHARED, 0)) {
		return MR_FAILURE;
	}

	return MR_SUCCESS;
}

int CMrBloom::MrBloomCheck(UCHAR* puszBloom, UINT uiLength, bool bProc)
{
	UINT uiCount = 0;
	UCHAR ucBloom = '\0';
	int iReturn = MR_SUCCESS;
	UCHAR uszMask[] = {MR_BLOOM_0, MR_BLOOM_1, MR_BLOOM_2, MR_BLOOM_3, MR_BLOOM_4, MR_BLOOM_5, MR_BLOOM_6, MR_BLOOM_7};

	while (uiCount < uiLength / sizeof(UINT)) {
		MrFileMmapGet(MR_BLOOM_BASE * uiCount + *(UINT*)puszBloom / 8, &ucBloom, sizeof(UCHAR), bProc);
		if (uszMask[*(UINT*)puszBloom % 8] != (ucBloom & uszMask[*(UINT*)puszBloom % 8])) {
			iReturn = MR_FAILURE;
			break;
		}
		puszBloom += sizeof(UINT);
		ucBloom = '\0';
		uiCount += 1;
	}

	return iReturn;
}

void CMrBloom::MrBloomUpdate(UCHAR* puszBloom, UINT uiLength, bool bProc)
{
	UINT uiCount = 0;
	UCHAR ucBloom = '\0';
	UCHAR uszMask[] = {MR_BLOOM_0, MR_BLOOM_1, MR_BLOOM_2, MR_BLOOM_3, MR_BLOOM_4, MR_BLOOM_5, MR_BLOOM_6, MR_BLOOM_7};

	while (uiCount < uiLength / sizeof(UINT)) {
		ucBloom = uszMask[*(UINT*)puszBloom % 8];
		MrFileMmapPut(MR_BLOOM_BASE * uiCount + *(UINT*)puszBloom / 8, &ucBloom, sizeof(UCHAR), bProc);
		puszBloom += sizeof(UINT);
		ucBloom = '\0';
		uiCount += 1;
	}

	return;
}

void CMrBloom::MrFileMmapGet(UINT uiOffset, UCHAR* puszLine, UINT uiLength, bool bProc)
{
	UCHAR* puszCur = (UCHAR*)m_pFile;

	if (NULL != puszCur) {
		puszCur += uiOffset;
		if (true == bProc) {
			if (MR_SUCCESS == MrFileFcntl(MR_F_RDLCK, MR_S_CUR, uiOffset, uiLength, MR_F_SETLKW)) {
				*puszLine = *puszCur;
				MrFileFcntl(MR_F_UNLCK, MR_S_CUR, uiOffset, uiLength, MR_F_SETLK);
			}
		}
		else {
			*puszLine = *puszCur;
		}
	}

	return;
}

void CMrBloom::MrFileMmapPut(UINT uiOffset, UCHAR* puszLine, UINT uiLength, bool bProc)
{
	UCHAR* puszCur = (UCHAR*)m_pFile;

	if (NULL != puszCur) {
		puszCur += uiOffset;
		if (true == bProc) {
			if (MR_SUCCESS == MrFileFcntl(MR_F_WRLCK, MR_S_CUR, uiOffset, uiLength, MR_F_SETLKW)) {
				*puszCur |= *puszLine;
				MrFileFcntl(MR_F_UNLCK, MR_S_CUR, uiOffset, uiLength, MR_F_SETLK);
			}
		}
		else {
			*puszCur |= *puszLine;
		}
	}

	return;
}
